package com.chinanet.repository.netelement;

import com.chinanet.entry.netelement.QWorking;
import com.chinanet.entry.netelement.Working;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.dsl.StringPath;
import lombok.NonNull;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.querydsl.binding.MultiValueBinding;
import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer;
import org.springframework.data.querydsl.binding.QuerydslBindings;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RestResource;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

public interface WorkingRepository extends PagingAndSortingRepository<Working, Long>  , QuerydslBinderCustomizer<QWorking>,QuerydslPredicateExecutor<Working> {

    Working findByName(@Param("name") String name);

    @Query(value = "select count(*) from working where name =:name", nativeQuery = true)
    int findByNameAntCount(@Param("name") String name);

    @RestResource(path = "name",rel = "name")
    @Query(value = "select * from working where name like concat('%',:name,'%')", nativeQuery = true)
    Page<Working> findAllByName(@Param("name") String name, Pageable pageable);

    @RestResource(path = "work",rel = "work")
    @Query(value = "select * from working where work like concat('%',:work,'%')", nativeQuery = true)
    Page<Working> findAllByWork(@Param("work") String work, Pageable pageable);

    @RestResource(path = "workAndNull",rel = "workAndNull")
    @Query(value = "select * from working where work is null", nativeQuery = true)
    Page<Working> findAllByWorkIsNull(Pageable pageable);

    @Transactional
    @Modifying
    @Query(value = "update working set bigkind = :bigkind where work like concat('%',:work,'%')", nativeQuery = true)
    void updateWork(@Param("work") String work,@Param("bigkind") int bigKind );

    @RestResource(path = "workAndList",rel = "workAndList")
    @Query(value = "select * from working where work like concat('%',:work,'%')", nativeQuery = true)
    List<Working> findAllByWork(@Param("work") String work);

    @RestResource(path = "nameAndWork",rel = "nameAndWork")
    @Query(value = "select * from working where name like concat('%',:name,'%') and work like concat('%',:work,'%')", nativeQuery = true)
    Page<Working> findAllByNameAndWork(@Param("name") String name, @Param("work") String work, Pageable pageable);

    @RestResource(path = "group",rel = "group")
    @Query(value = "select * from working group by work,bigkind", nativeQuery = true)
    public Page<Working> findAllAndGroup(Pageable p);

    @RestResource(path = "bigkindAndGroup",rel = "bigkindAndGroup")
    @Query(value = "select * from working where bigkind =:bigkind group by work,bigkind", nativeQuery = true)
    Page<Working> findAllByBigkindAndGroup(@Param("bigkind") int bigKind , Pageable pageable);

    @RestResource(path = "bigkindAndNameAndGroup",rel = "bigkindAndNameAndGroup")
    @Query(value = "select * from working where bigkind = :bigkind and name like concat('%',:name,'%') group by work,bigkind",nativeQuery = true)
    List<Working> findAllByBigkindAndNameAndGroup(@Param("bigkind") int bigkind, @Param("name") String name );

    default void customize(@NonNull  QuerydslBindings bindings, @NonNull QWorking
            working) {
/*        bindings.bind(relation.na
me).first((path, value) -> path.contains(value));*/
        // bindings.bind(working.name).first((path, value) -> path.containsIgnoreCase(value));
        bindings.bind(String.class).all((MultiValueBinding<StringPath,String>) (path,values) -> {
            // 中文乱码解决问题
/*            try {
                String newValue=URLDecoder.decode(values,"UTF-8");
                System.out.println(path);
                System.out.println(newValue);
                return  path.contains(newValue);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                return  null;
            }*/
            BooleanBuilder predicate=new BooleanBuilder();
            values.forEach(value -> predicate.or(path.contains(value)));
            return Optional.of(predicate);
        });
    }
}